#include "Game.h"



using namespace std;


/**
 * Prints a Menu to the Player of where he/she can go
 * and then asks where to go.
 * This function checks border of the map and cell availability
 * @param void
 * @return char - choice of the user
 */
char Game::printMoveMenu()
{
	char			cChoice = 0;
	bool			bHappy = false;

	while (!bHappy)
	{
		system("cls");
		printLocationInformation();
		cout << "/./././././././././././././././././././././././././././././././" << endl;
		cout << "./././././././././././././././././././././././././././././././." << endl;
		cout << "/./././././ Directions  " << endl;
		cout << "''''''''''''''''''''''''" << endl;
		cout << "Which direction do you choose?" << endl;
		if (m_currentMap->checkWest(m_playerCoord))
		{
			cout << "-> Go [W]est" << endl;
		}
		if (m_currentMap->checkEast(m_playerCoord))
		{
			cout << "-> Go [E]ast" << endl;
		}
		if (m_currentMap->checkSouth(m_playerCoord))
		{
			cout << "-> Go [S]outh" << endl;
		}
		if (m_currentMap->checkNorth(m_playerCoord))
		{
			cout << "-> Go [N]orth" << endl;
		}
		cin >> cChoice;
		if ((cChoice == 'w') || (cChoice == 'W') ||
			(cChoice == 's') || (cChoice == 'S') ||
			(cChoice == 'e') || (cChoice == 'e') ||
			(cChoice == 'n') || (cChoice == 'n'))
			bHappy = true;
		cout << endl;
		system("cls");
	}
	return cChoice;
}


/**
 * This function checks what is happening every time a Player enters a cell on the map.
 * TODO: 3/ change map
 * @param MapCell cell
 * @return void
 */
void Game::processCellInfo(MapCell cell)
{
	if (processCellEncounter(cell) == false)
	{
		processCellMapChange(cell);
	}
}


/**
 * for each map in memory
 * compare the content of the cell with the id of the map
 * if they are the same and there is a cell in the destination map to go back
 * then we teleport the player
 * @param MapCell cell
 * @return bool - true if the map has changed
 */
bool Game::processCellMapChange(MapCell cell)
{
	for (unsigned int i = 0; i < m_maps.size(); ++i)
	{
		if (cell.getContent().compare(m_maps[i]->getID()) == 0)
		{
			if (m_maps[i]->findCell(m_currentMap->getID(), m_playerCoord))
			{
				m_currentMap = m_maps[i];
				return true;
			}
		}
	}
	return false;
}


/**
 * 1/ check if the content is a specific monster. in this case we create an occurence
 * 2/ if we have a random encounter then the random encounter table of the terrain is checked
 *  If a monster has been created then the fighting procedure is launched.
 * @see newEncounter()
 * @see processFightMenu()
 * @see printFightMenu()
 * @param MapCell cell
 * @return bool - true if a monster was encountered
 */
bool Game::processCellEncounter(MapCell cell)
{
	Monster* newMonster = 0;

	newMonster = newEncounter(cell.getContent());
	if (newMonster == 0)
	{
		if (cell.getContent().compare(MAPCELL_CONTENT_RNDENC) == 0)
		{
			for (unsigned int i = 0; i < m_terrains.size(); ++i)
			{
				if (cell.getType().compare(m_terrains[i]->getName()) == 0)
				{
					newMonster = newEncounter(m_terrains[i]->getRandomEncounter());
				}
			}
		}
	}
	if (newMonster !=0)
	{
		while (!processFightMenu(printFightMenu(newMonster), newMonster)) ;
		delete newMonster;
		return true;
	}
	return false;
}


/**
 * Generates a new NPC.
 * Checks if the monster exists in the monster list and returns an instance.
 * @param std::string npc - name of the NPC to create
 * @return Monster* - 0 if no NPC is in the m_monsters list else a pointer to a new Monster is returned
 */
Monster* Game::newEncounter(std::string npc)
{
	for (unsigned int i = 0; i < m_monsters.size(); ++i)
	{
		if (!(m_monsters[i]->getName().compare(npc)))
		{
			Monster* newMonster = new Monster;
			*(newMonster) = *(m_monsters[i]);
			newMonster->generate();
			return newMonster;
		}
	}
	return 0;
}


/**
 * Changes the position of the player according to his choice
 * And process event described in the cell
 * @see processCellInfo()
 * @param char choice 
 * @return void
 */
void Game::processMoveMenu(char choice)
{
	switch (choice)
	{
	case 'w':
	case 'W':
		if (m_currentMap->checkWest(m_playerCoord))
		{
			--m_playerCoord.x;
		}
		break;
	case 's':
	case 'S':
		if (m_currentMap->checkSouth(m_playerCoord))
		{
			--m_playerCoord.y;
		}
		break;
	case 'e':
	case 'E':
		if (m_currentMap->checkEast(m_playerCoord))
		{
			++m_playerCoord.x;
		}
		break;
	case 'n':
	case 'N':
		if (m_currentMap->checkNorth(m_playerCoord))
		{
			++m_playerCoord.y;
		}
		break;
	default:
		break;
	}
	processCellInfo(m_currentMap->m_cells(m_playerCoord.x, m_playerCoord.y));
}